package secondriver.springsubway.scaffold;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * Not Test
 * 
 * @author secondriver
 * @created 2015-5-5 下午8:39:42
 * 
 */
public class InterfaceImplements {

	/**
	 * 获取指定接口的所有实现类
	 * 
	 * @param inf
	 * @return
	 * @throws ClassNotFoundException
	 * @throws IOException
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List<Class> getAllImplementsClassByInterface(Class inf)
			throws ClassNotFoundException, IOException {
		List<Class> returnClassList = new ArrayList<Class>(16);
		if (inf.isInterface()) {
			String packageName = inf.getPackage().getName();
			List<Class> allClassInPackage = getAllClassByPackageName(packageName);
			for (int i = 0, s = allClassInPackage.size(); i < s; i++) {
				Class c = allClassInPackage.get(i);
				if (inf.isAssignableFrom(c)) {
					if (!inf.equals(c)) {
						returnClassList.add(c);
					}
				}
			}
		}
		return returnClassList;
	}

	/**
	 * 查找指定包下的所有类,jar中不做处理
	 * 
	 * @param packageName
	 * @return
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("rawtypes")
	private static List<Class> getAllClassByPackageName(String packageName)
			throws IOException, ClassNotFoundException {
		ClassLoader classLoader = Thread.currentThread()
				.getContextClassLoader();
		String path = packageName.replace(".", "/");
		Enumeration<URL> resources = classLoader.getResources(path);
		List<File> dirs = new ArrayList<File>();
		while (resources.hasMoreElements()) {
			URL resource = resources.nextElement();
			dirs.add(new File(resource.getFile()));
		}
		List<Class> classes = new ArrayList<Class>();
		for (File dir : dirs) {
			classes.addAll(findClasses(dir, packageName));
		}
		return classes;
	}

	/**
	 * 获取指定目录下的类
	 * 
	 * @param dir
	 * @param packageName
	 * @return
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("rawtypes")
	private static List<Class> findClasses(File dir, String packageName)
			throws ClassNotFoundException {
		List<Class> classes = new ArrayList<Class>();
		if (!dir.exists()) {
			return classes;
		}
		File[] files = dir.listFiles();
		for (File file : files) {
			String fileName = file.getName();
			if (file.isDirectory()) {
				classes.addAll(findClasses(file, packageName + "." + fileName));
			} else if (file.getName().endsWith(".class")) {
				classes.add(Class.forName(packageName + "."
						+ fileName.substring(0, fileName.length() - 6)));
			}
		}
		return classes;
	}

}
